<!DOCTYPE html>
<html lang=en>

<head>
  <meta charset=UTF-8>
  <meta http-equiv=X-UA-Compatible content="IE=edge">
  <meta name=viewport content="width=device-width,initial-scale=1">
  <title>Document</title>
  <style>
  
    
    body {
      --err-color: #c81623;
      --rig-color: #277c32;

      --sel-color: #333;
      --bg:#fff;
      /* --fc:#333; */
    }
    @media (prefers-color-scheme: dark) {
    body {
        --sel-color: #eee;
        --bg: #333;
      }
    }

    body{
      background-color: var(--bg);
      color: var(--sel-color)
    }

    header {
      position: fixed;
      top: 0;
      left: 0;
      right:0;
      width: 100%;
      z-index:9999;
      background-color: var(--bg);
    }
    header h2{
      text-align: center;
    }
    section {
      margin: 4em 8em;
    }
    
    #app {
      padding: 20px;
      margin: 20px auto
    }
    a{color:var(--sel-color)}

    footer{
      text-align: center
    }

    .subtitle {
      font-weight: 700;
      font-size: 16px
    }

    .ans-item {
      margin: 5px;
      padding: 5px;
      border: 1px solid #ccc5;
      cursor: pointer;
      border-radius: 5px;
      display: flex;
      align-items: center;
      position: relative
    }

    .ans-item-label {
      cursor: pointer;
      width: 2em;
      position: absolute;
      top: -1px;
      bottom: -1px;
      left: -1px;
      display: flex;
      border-top-left-radius: 5px;
      border-bottom-left-radius: 5px
    }

    .ans-item-label-char {
      margin: auto;
      position: relative
    }

    .ans-item-label-char::after {
      position: absolute;
      content: '';
      height: 1em;
      width: 1px;
      background-color: #ccc;
      top: 2px;
      right: -10px
    }

    .ans-item-content {
      margin-left: 2em;
    }

    .ans-item.selected .ans-item-label {
      font-size: large;
    }

    .ans-item.selected {
      border-color: var(--sel-color);
    
    }

    .ans-item.error {
      border: 1px solid var(--err-color) !important
    }

    .ans-item.right {
      border: 1px solid var(--rig-color) !important
    }

    .ans-item.error .ans-item-label {
      /* background-color: var(--err-color) */
    }

    .ans-item.right .ans-item-label {
      /* background-color: var(--rig-color) */
    }

    .dialog-container {
      position: fixed;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
      background-color: rgba(0, 0, 0, .5)
    }

    .dialog {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background-color: var(--bg);
      width: 80%;
      max-width: 600px;
    }

    .score {
      text-align: center
    }

    .ans-area {
      padding: 10px;
      display: flex;
      flex-wrap: wrap;
      justify-content:flex-start;
    }

    .ans-area-item {
      width: 2em;
      height: 2em;
      border-radius: 1em;
      line-height: 2em;
      text-align: center;
      margin: .2em .2em;
      color: #fff
    }

    .ans-area-item.right {
      background-color: teal
    }

    .ans-area-item.error {
      background-color: var(--err-color)
    }

    .resultContainer {
      display: flex;
      justify-content: space-around
    }
    dd,
    dl,
    dt {
      margin: 0;
      text-align: center
    }
    .error{
      color: var(--err-color);
    }
    .right{
      color: var(--rig-color);
    }
    .idx_item{
      margin:2px;
      height: 1px;
      background-color: #ccc;

    }
    .idx_item.selected{
      background-color: var(--sel-color);
      height: 2px;
    }
    button {
      border-radius: 8px;
      border: 1px solid transparent;
      padding: 0.6em 1.2em;
      font-weight: 500;
      cursor: pointer;
    }

  </style>
</head>

<body>
  <div id="app">
    <header>
      <h2>{{name}}-测试题</h2>
      <div class="idx" style="display:flex;justify-content: center">
        <span v-for="(item,idx) in list"
        class="idx_item"
          :class="{'selected': ans[idx]}"
        :style="{width:80/list.length +'%'}">
        </span>
      </div>
    </header>
    <section>
      <div>
        <p>说明：{{desc}}</p>
        <p>最新修改时间：{{lastModDate}}</p>
      </div>
      <div v-for="(sub, idx) in list" :key=idx>
        <h6 class=subtitle>{{idx+1}}/{{list.length}} [{{sub.type}}]</h6>
        <div v-html="html(sub.subjectName)"></div>
        <div
        v-for="(op,index) in sub.options"
        :key="index" 
        @click="check(idx,index)"
        class="ans-item"
        :class="comCla(idx,index)">
          <label class=ans-item-label>
            <span
              class=ans-item-label-char>
              {{String.fromCharCode("A".charCodeAt(0) + index)}}</span>
            </label>
          <p class=ans-item-content>{{op}}</p>
        </div>
        <div v-if="state==='viewAnalysis'" :class="yourAns[idx]===rightAns[idx]?'right':'error'">
          <p><b>正确答案: {{rightAns[idx]}}</b> <b>你的答案:{{yourAns[idx]}}</b></p>
          <div>答案解析： {{sub.explain}}</div>
        </div>
      </div>
      <div style="text-align:center;margin:30px 0 50px">
        <button
          v-if="state!=='viewAnalysis'"
          :disabled=!isDone
          @click=finished>{{isDone?'提交':'做完才能再提交'}}</button>
          <button 
          v-else 
          @click="hAgain">重来</button>
      </div>
      <div v-if=showDialog class=dialog-container @click.self="showDialog=false">
        <div class=dialog>
          <h2 style=text-align:center>成绩单</h2>
          <h3 class=score>{{mark}} 分</h3>
          <div class=ans-area><span style="color:#fff;" v-for="(it,idx) in markList" class=ans-area-item
              :class="it ? 'right' : 'error'">{{idx + 1}}</span></div>
          <div style="text-align:center;margin: 30px 0 50px;">
            <button @click=viewAnalysis>看解析</button>
            <button @click="showDialog=false">继续做</button>
            <button @click="hAgain">重来</button>
            </div>
        </div>
      </div>
    </section>
    <footer>@凡人进阶 <a href="./index.html">更多</a></footer>
  </div>
  <script>
    /* eslint-disable camelcase */
/* eslint-disable no-undef */
;(function (name, definition) {
const hasDefine = typeof define === 'function'
const hasExports = typeof module !== 'undefined' && module.exports

if (hasDefine) {
  define(definition)
} else if (hasExports) {
  module.exports = definition()
} else {
  this[name] = definition()
}
})('hexMd5', function () {
const hexcase = 0 /* hex output format. 0 - lowercase; 1 - uppercase        */
const chrsz = 8 /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
* These are the functions you'll usually want to call
* They take string arguments and return either hex or base-64 encoded strings
*/
function hexMd5 (s) { return binl2hex(core_md5(str2binl(s), s.length * chrsz)) }

/*
* Calculate the MD5 of an array of little-endian words, and a bit length
*/
/* append padding */
function core_md5 (x, len) {
  x[len >> 5] |= 0x80 << ((len) % 32)
  x[(((len + 64) >>> 9) << 4) + 14] = len

  let a = 1732584193
  let b = -271733879
  let c = -1732584194
  let d = 271733878

  for (let i = 0; i < x.length; i += 16) {
    const olda = a
    const oldb = b
    const oldc = c
    const oldd = d

    a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936)
    d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586)
    c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819)
    b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330)
    a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897)
    d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426)
    c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341)
    b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983)
    a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416)
    d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417)
    c = md5_ff(c, d, a, b, x[i + 10], 17, -42063)
    b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162)
    a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682)
    d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101)
    c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290)
    b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329)

    a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510)
    d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632)
    c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713)
    b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302)
    a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691)
    d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083)
    c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335)
    b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848)
    a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438)
    d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690)
    c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961)
    b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501)
    a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467)
    d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784)
    c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473)
    b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734)

    a = md5_hh(a, b, c, d, x[i + 5], 4, -378558)
    d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463)
    c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562)
    b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556)
    a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060)
    d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353)
    c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632)
    b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640)
    a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174)
    d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222)
    c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979)
    b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189)
    a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487)
    d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835)
    c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520)
    b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651)

    a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844)
    d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415)
    c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905)
    b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055)
    a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571)
    d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606)
    c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523)
    b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799)
    a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359)
    d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744)
    c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380)
    b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649)
    a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070)
    d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379)
    c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259)
    b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551)

    a = safe_add(a, olda)
    b = safe_add(b, oldb)
    c = safe_add(c, oldc)
    d = safe_add(d, oldd)
  }
  return Array(a, b, c, d)
}

/*
* These functions implement the four basic operations the algorithm uses.
*/
function md5_cmn (q, a, b, x, s, t) {
  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b)
}
function md5_ff (a, b, c, d, x, s, t) {
  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t)
}
function md5_gg (a, b, c, d, x, s, t) {
  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t)
}
function md5_hh (a, b, c, d, x, s, t) {
  return md5_cmn(b ^ c ^ d, a, b, x, s, t)
}
function md5_ii (a, b, c, d, x, s, t) {
  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t)
}

/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safe_add (x, y) {
  const lsw = (x & 0xFFFF) + (y & 0xFFFF)
  const msw = (x >> 16) + (y >> 16) + (lsw >> 16)
  return (msw << 16) | (lsw & 0xFFFF)
}

/*
* Bitwise rotate a 32-bit number to the left.
*/
function bit_rol (num, cnt) {
  return (num << cnt) | (num >>> (32 - cnt))
}

/*
* Convert a string to an array of little-endian words
* If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
*/
function str2binl (str) {
  const bin = Array()
  const mask = (1 << chrsz) - 1
  for (let i = 0; i < str.length * chrsz; i += chrsz) { bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32) }
  return bin
}

/*
* Convert an array of little-endian words to a hex string.
*/
function binl2hex (binarray) {
  const hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef'
  let str = ''
  for (let i = 0; i < binarray.length * 4; i++) {
    str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) +
         hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF)
  }
  return str
}
return hexMd5
})

  </script>
  <script src="./md.js"></script>
  <script src="./vue.min.js"></script>
  <script>
    const d={list:[{id:1632730220724,key:39,subjectName:"观察如下代码：\n```\nimport {mapMutations} from 'vuex'\nexport default {\n  methods:{\n     ...mapMutations([\"counter\"]),\n     c1() {}\n  }\n}\n```\n下面的说法错误是哪一项？\n",type:"单选题",tagName:"vue",explain:"",options:["mapMutations是vuex中的一个方法","mapMutations的返回值是一个数组mapMutations的返回值是一个数组mapMutations的返回值是一个数组mapMutations的返回值是一个数组mapMutations的返回值是一个数组mapMutations的返回值是一个数组","mapMutations的返回值是一个对象","....实现了对象的填充"],ans:["e28840e28cd5d6cb374b9ef9756064ff"]},{id:1632730176626,key:38,subjectName:"补全如下使用vuex时的伪代码：\n```\nimport Vuex from 'vuex'\nvar store = new ________\nexport default store\n```\n把new后面缺少的代码补起来。\n",type:"单选题",tagName:"react",explain:"",options:["Vuex.Store({})","Vuex({})","Vuex.State({})","Vuex.state({})"],ans:["0c7c2cd8a062e519aed7d49a95e6b352"]},{id:1632730121972,key:37,subjectName:"有如下mutations\n```\nnew Vuex.Store({\n  mutations:{\n    m1(state){\n     }\n  }\n}) \n```\n请问，在组件中通过this.$____._____可以来调用它？",type:"单选题",tagName:"react",explain:"",options:["this.$store.commit('m1')","this.$store.commit(m1)","this.$state.commit('m1')","this.$state.commit(m1)"],ans:["ba62a2da0366a636fa5aafa340535a08"]}],desc:"xxx",dt:"1632730268534",num:"13",name:"vuex"}
  </script>
  <script>
    // 乱序
  d.list.forEach(it => it.options.sort(()=>Math.random()>0.5?1:-1));
  const CHAR_MAP = { 0: "A", 1: "B", 2: "C", 3: "D",4:"E" }
  const encode = hexMd5
  new Vue({ 
    el: "#app", 
    data: { 
      name: d.name, 
      lastModDate:d.dt,
      desc:d.desc,
      state: "pending",
       markList: [], 
       mark: 0, 
       list: d.list.sort(()=>Math.random()>0.5?1:-1), 
       ans: {}, 
       yourAns: {}, 
       rightAns: {}, 
       showDialog:false 
      },
    computed: { 
      isDone() { 
        var s = this.list;
        t = s.length && Object.keys(this.ans).length === s.length, s = Object.values(this.ans).every(s => Object.values(s).some(s => s)); return t && s } 
    }, 
    methods: { 
      hAgain(){
        window.location.reload();
        document.documentElement.scrollTop = 0;
      },
      html(txt) {
        // return marked.parse(txt)
        return markdown.toHTML(txt)
      },
      comCla(s, t) { 
        const { ans: n, state: e, rightAns: i, markList: a } = this, r = []; 
        return n[s] && n[s][t] && r.push("selected"), "viewAnalysis" === e && (a[s] ? i[s].includes(CHAR_MAP[t]) && r.push("right") : i[s].includes(CHAR_MAP[t]) && r.push("error")), r 
      }, 
      check(s, t) {
        const n = { ...this.ans }; 
        if (1 < this.list[s].ans.length) n[s] || (n[s] = {}), n[s][t] = !n[s][t]; else { for (var e in n[s] || (n[s] = {}), n[s]) n[s][e] = !1; n[s][t] = !n[s][t] } this.ans = n 
        console.log(this.ans)
      }, 
      viewAnalysis() { 
        this.state = "viewAnalysis", 
        this.showDialog = false
      }, 
      computedMark(s, t = 100) {
        const e = this["list"]; 
        var n = e.filter(s => 1 < s.ans.length).length;
        const i = t / (1.5 * n + (e.length - n)); 
        const mark = s.reduce((s, t, n) => t ? s + (1 < e[n].ans.length ? 1.5 * i : i) : s, 0) 
        return Math.ceil(mark)
      }, 
      checkAns(e) { 
        return this.list.map((s, t) => { if (s.ans.length !== e[t].length) return !1; const n = e[t].map(s => encode(s)); return s.ans.every(s => n.includes(s)) }) 
      }, 
      formatAns() { 
        const t = {}; 
        for (var n in this.ans) { 
          let s = ""; var e, i = this.ans[n]; for (e in i) i[e] && (s += CHAR_MAP[e]); t[n] = s 
        }
        var s = this.list.reduce((s, t, n) => { const e = t.options.map(s => encode(s)); return s[n] = t.ans.map(t => e.findIndex(s => s === t)).map(s => CHAR_MAP[s]).join(""), s }, {}); 
        this.yourAns = t;
        Object.keys(s).forEach(key => {
          s[key] = s[key].split('').sort().join('')
        })
        this.rightAns = s; 
        console.log(s,t)
      }, 
      finished() { 
        this.formatAns(); 
        var s = this.list.map((s, t) => { const n = this.ans[t]; return n ? s.options.filter((s, t) => n[t]) : null }), s = this.checkAns(s); this.markList = s, this.mark = this.computedMark(s), this.showDialog = !0 } 
      } 
    })
  </script>
</body>
</html>